package edu.neu.cs6515.xml.converter;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

import edu.neu.cs6515.xml.False;
import edu.neu.cs6515.xml.Tile;
import edu.neu.cs6515.xml.w12.Rerack;
import edu.neu.cs6515.xml.w12.True;

public class AdminResponseConverter implements Converter {

    @Override
    public boolean canConvert(final Class type) {
        return (True.class.equals(type) ||
                False.class.equals(type) ||
                Tile.class.equals(type) || Rerack.class.equals(type));
    }

    @Override
    public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) {
        if (source instanceof Tile) {
            Tile tile = (Tile) source;
            writer.startNode("tile");
            context.convertAnother(tile);
            writer.endNode();
        } else if (source instanceof Rerack) {
            Rerack rerack = (Rerack) source;
            for (Tile tile : rerack.getTile()) {
                writer.startNode("tile");
                context.convertAnother(tile);
                writer.endNode();
            }
        }
    }

    @Override
    public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) {
        Object obj;
        String nodeName = reader.getNodeName();
        if (nodeName.equals("true")) {
            obj = new True();
        } else if (nodeName.equals("false")) {
            obj = new False();
        } else if (nodeName.equals("tile")) {
            Tile tile = (Tile) new TileConverter().unmarshal(reader, context);
            obj = tile;
        } else {
            List<Tile> tiles = new ArrayList<Tile>();
            while (reader.hasMoreChildren()) {
                reader.moveDown();
                Tile tile = (Tile) new TileConverter().unmarshal(reader, context);
                tiles.add(tile);
                reader.moveUp();
            }
            obj = new Rerack(tiles);
        }
        return obj;
    }

}
